/*
Author: Surpass-HC
Source: https://gitee.com/hxchuan000/clpc-1
Mail: surpass-hc@qq.com
*/
#include <clptcCmdList.h>
// #include <clptcCmdHeart.h>
#include <crcCalc.h>
#include <hexstr.h>
#include <parmNorm.h>
#include <clptcDlgItf.h>
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
#include <fileOpt.h>
#endif
const DEV_C51_CODE_FLAG char *CLPTC_SUB_VERSION = "LPTC-A-STD-V1.1.2503300009";

// =============command rwSn(write or read serial number) begin=====================
void clptcCmdFuncOvtSnd_rwSn(clptcCmdStcSnd_rwSn *idt)
{
    idt = NULL;
}
void clptcCmdFuncOvtResp_rwSn(clptcCmdStcResp_rwSn *odt)
{
    odt = NULL;
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_rwSn(clptcParseStc *ptcptr, clptcCmdUnion_rwSn *iodt)
{
    if (memcmp(parmNormIstc.sn, CLPTC_SLAVE_SN_DEFAULT, CLPTC_SLAVE_SN_SIZE) == 0)
    {
        logHexBufStr("sub cfg sn ok, my sn", parmNormIstc.sn, sizeof(parmNormIstc.sn));
        logHexBufStr("sub cfg sn ok, cfg sn", iodt->idt.wSn, sizeof(iodt->idt.wSn));
        memcpy(parmNormIstc.sn, iodt->idt.wSn, CLPTC_SLAVE_SN_SIZE);
        // save param
        parmNormSave(parmNormIstc.flashSvAddr);
    }
    else
    {
        logHexBufStr("sub cfg sn fail, my sn", parmNormIstc.sn, sizeof(parmNormIstc.sn));
        logHexBufStr("sub cfg sn fail, cfg sn", iodt->idt.wSn, sizeof(iodt->idt.wSn));
    }
    memcpy(iodt->odt.rSn, parmNormIstc.sn, CLPTC_SLAVE_SN_SIZE);

    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_rwSn(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_rwSn *packDt)
{
    clptcCmdStcSnd_rwSn *tmpdata = (clptcCmdStcSnd_rwSn *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_rwSn));
    memcpy(ptcptr->hostSndInf, packDt->wSn, sizeof(tmpdata->wSn));
    // over turn user data.
    clptcCmdFuncOvtSnd_rwSn(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_rwSn, sizeof(clptcCmdStcSnd_rwSn));
}
int clptcCmdFuncHostDoResp_rwSn(clptcParseStc *ptcptr, clptcCmdStcResp_rwSn *odt)
{
    // logdebugcHexBuf(odt->rSn, sizeof(odt->rSn));
    if (memcmp(ptcptr->hostSndInf, odt->rSn, sizeof(odt->rSn)) != 0)
    {
        logHexBufStr("host cfg sn fail, cfg sn", (const char *)ptcptr->hostSndInf, sizeof(odt->rSn));
        logHexBufStr("host cfg sn fail, sub sn", odt->rSn, sizeof(odt->rSn));
    }
    else
    {
        logHexBufStr("host cfg sn ok, cfg sn", (const char *)ptcptr->hostSndInf, sizeof(odt->rSn));
        logHexBufStr("host cfg sn ok, sub sn", odt->rSn, sizeof(odt->rSn));
    }
    return 1;
}
#endif
// =============command rwSn(write or read serial number) begin=====================

// =============command rwAddr(write or read address) begin=====================
void clptcCmdFuncOvtSnd_rwAddr(clptcCmdStcSnd_rwAddr *idt)
{
    idt = NULL;
}
void clptcCmdFuncOvtResp_rwAddr(clptcCmdStcResp_rwAddr *odt)
{
    odt = NULL;
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_rwAddr(clptcParseStc *ptcptr, clptcCmdUnion_rwAddr *iodt)
{
    if (memcmp(parmNormIstc.sn, iodt->idt.cfgSn, CLPTC_SLAVE_SN_SIZE))
    {
        logdebugc("sn is diff, not set my addr!");
        ptcptr->subRespStatFlag = clptcCmdResp_NotSndBack;
        return;
    }
    logdebugc("sub cfg add:rw=%d,my=%d,set=%d", iodt->idt.rwflag, parmNormIstc.addr485, iodt->idt.wAddr);
    if (iodt->idt.rwflag)
    {
        parmNormIstc.addr485 = iodt->idt.wAddr;
        // save param
        parmNormSave(parmNormIstc.flashSvAddr);
    }
    iodt->odt.rAddr = parmNormIstc.addr485;
    // clptcSetAddrV1(ptcptr, parmNormIstc.addr485);

    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_rwAddr(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_rwAddr *packDt)
{
    clptcCmdStcSnd_rwAddr *tmpdata = (clptcCmdStcSnd_rwAddr *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_rwAddr));
    ptcptr->hostSndInf[0] = packDt->wAddr;
    // over turn user data.
    clptcCmdFuncOvtSnd_rwAddr(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_rwAddr, sizeof(clptcCmdStcSnd_rwAddr));
}
int clptcCmdFuncHostDoResp_rwAddr(clptcParseStc *ptcptr, clptcCmdStcResp_rwAddr *odt)
{
    if (ptcptr->hostSndInf[0] != odt->rAddr)
    {
        logerrorc("host set addr error:%d!=%d", ptcptr->hostSndInf[0], odt->rAddr);
        // return -1;
    }
    else
    {
        logdebugc("host set addr ok:%d=%d", ptcptr->hostSndInf[0], odt->rAddr);
    }
    return 1;
}
#endif
// =============command rwAddr(write or read address) end======================

// =============command getInf begin=====================
void clptcCmdFuncOvtSnd_getInf(clptcCmdStcSnd_getInf *idt)
{
    idt = NULL;
}
void clptcCmdFuncOvtResp_getInf(clptcCmdStcResp_getInf *odt)
{
    // odt->dlgcrc = ovtBigSys16(odt->dlgcrc);
    odt = NULL;
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_getInf(clptcParseStc *ptcptr, clptcCmdUnion_getInf *iodt)
{
    memset(iodt->odt.rvers, 0, sizeof(iodt->odt.rvers));
    memcpypro(iodt->odt.rvers, sizeof(iodt->odt.rvers), parmNormIstc.ver, sizeof(parmNormIstc.ver));
    memcpy(iodt->odt.rsn, parmNormIstc.sn, CLPTC_SLAVE_SN_SIZE);
    memset(iodt->odt.devInfo, 0, sizeof(iodt->odt.devInfo));
    logdebugc("sub get sub ok!");
    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_getInf(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_getInf *packDt)
{
    // over turn user data.
    // clptcCmdFuncOvtSnd_getInf(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_getInf, sizeof(clptcCmdStcSnd_getInf));
}
int clptcCmdFuncHostDoResp_getInf(clptcParseStc *ptcptr, clptcCmdStcResp_getInf *odt)
{
    logdebugc("host get sub[%d] info ok! vers: %s", clptcGetAddrV1(ptcptr), odt->rvers);
    logHexBufStr("host get info sn", odt->rsn, sizeof(odt->rsn));
    return 1;
}
#endif
// =============command getInf end======================

// =============command setsm4key begin=====================
#if CLPTC_CPL_USE_CRYPTE
static void clptcCalcDlgKeyCrc(const char *inkey, char *outcrc, int keysize)
{
    char tmpval = 0;
    int i;
    for (i = 0; i < keysize; i++)
    {
        tmpval = (i + 0xa5);
        outcrc[i] = (inkey[i] ^ tmpval) + tmpval;
    }
}
#endif
void clptcCmdFuncOvtSnd_setsm4key(clptcCmdStcSnd_setsm4key *idt)
{
    idt = NULL;
}
void clptcCmdFuncOvtResp_setsm4key(clptcCmdStcResp_setsm4key *odt)
{
    odt = NULL;
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_setsm4key(clptcParseStc *ptcptr, clptcCmdUnion_setsm4key *iodt)
{
#if CLPTC_CPL_USE_CRYPTE
    // in, get inform command will set dialog key, so need crypte.
    if (clptcGetCrypteV1(ptcptr) != clptcCrypte_Sm4Pre)
    {
        logerrorc("");
        ptcptr->subRespStatFlag = clptcCmdResp_NdCrypt;
        return;
    }
    if (clptcDlgMgrSetKey(ptcptr->dFunInf->lpDlgMgr, 0, (const uint8_t *)iodt->idt.setkey) < 0)
    {
        logerrorc("");
        ptcptr->subRespStatFlag = clptcCmdResp_NdCrypt;
        return;
    }
    // out
    clptcCalcDlgKeyCrc((const char *)clptcDlgMgrGetKey(ptcptr->dFunInf->lpDlgMgr, 0), iodt->odt.keycrc, sizeof(iodt->odt.keycrc));

    logdebugc("sub setsm4key ok!");
    logHexBufStr("clptcCmdFuncSubDo_setsm4key set dlg key:", (const char *)clptcDlgMgrGetKey(ptcptr->dFunInf->lpDlgMgr, 0), sizeof(iodt->idt.setkey));
    logHexBufStr("clptcCmdFuncSubDo_setsm4key response dlg key crc:", iodt->odt.keycrc, sizeof(iodt->odt.keycrc));

    // ptcptr->subRespCrypteHostAddr = clptcCrypte_Sm4Pre;
#else
    logdebugc("sub setsm4key ok!");
    logHexBufStr("clptcCmdFuncSubDo_setsm4key set dlg key:", iodt->idt.setkey, sizeof(iodt->idt.setkey));
#endif
    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_setsm4key(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_setsm4key *packDt)
{
    clptcCmdStcSnd_setsm4key *tmpdata = (clptcCmdStcSnd_setsm4key *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_setsm4key));
#if CLPTC_CPL_USE_CRYPTE
    if (clptcDlgMgrSetKey(ptcptr->dFunInf->lpDlgMgr, packAddr, (const uint8_t *)packDt->setkey) < 0)
    {
        logerrorc("");
        return -1;
    }
    clptcCalcDlgKeyCrc((const char *)clptcDlgMgrGetKey(ptcptr->dFunInf->lpDlgMgr, packAddr), (char *)ptcptr->hostSndInf, sizeof(tmpdata->setkey));
    logHexBufStr("clptcCmdFuncHostPack_setsm4key keycrc:", (const char *)ptcptr->hostSndInf, sizeof(tmpdata->setkey));
#else
#endif
    // over turn user data.
    clptcCmdFuncOvtSnd_setsm4key(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_setsm4key, sizeof(clptcCmdStcSnd_setsm4key));
}
int clptcCmdFuncHostDoResp_setsm4key(clptcParseStc *ptcptr, clptcCmdStcResp_setsm4key *odt)
{
#if CLPTC_CPL_USE_CRYPTE
    if (clptcGetCrypteV1(ptcptr) != clptcCrypte_Sm4Pre)
    {
        logerrorc("host setsm4key crypte error:%d", clptcGetCrypteV1(ptcptr));
        return -1;
    }
    if (memcmp(ptcptr->hostSndInf, odt->keycrc, sizeof(odt->keycrc)) != 0)
    {
        logerrorc("host get info dkey crc error");
        logHexBufStr("clptcCmdFuncHostDoResp_setsm4key sub keycrc:", odt->keycrc, sizeof(odt->keycrc));
        logHexBufStr("clptcCmdFuncHostPack_setsm4key host keycrc:", (const char *)ptcptr->hostSndInf, sizeof(odt->keycrc));
        return -1;
    }
#endif
    logdebugc("host setsm4key ok!");
    return 1;
}
#endif
// =============command setsm4key end======================

// =============command heartBeat begin=====================
void clptcCmdFuncOvtSnd_heartBeat(clptcCmdStcSnd_heartBeat *idt)
{
    idt = NULL;
}
void clptcCmdFuncOvtResp_heartBeat(clptcCmdStcResp_heartBeat *odt)
{
    odt = NULL;
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_heartBeat(clptcParseStc *ptcptr, clptcCmdUnion_heartBeat *iodt)
{
    // // in
    logdebugc("sub rcv heart:%s", iodt->idt.hdata);
    // // out
    snprintf(iodt->odt.hdata, sizeof(iodt->odt.hdata), "sub heart[%d]", parmNormIstc.addr485);

    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    // ptcptr->subRespCrypteHostAddr = clptcCrypte_Sm4Dlg;
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
    return;
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_heartBeat(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_heartBeat *packDt)
{
    clptcCmdStcSnd_heartBeat *tmpdata = (clptcCmdStcSnd_heartBeat *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_heartBeat));
    ptcptr->hostSndInf[0] = packAddr;
    // over turn user data.
    clptcCmdFuncOvtSnd_heartBeat(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_heartBeat, sizeof(clptcCmdStcSnd_heartBeat));
}
int clptcCmdFuncHostDoResp_heartBeat(clptcParseStc *ptcptr, clptcCmdStcResp_heartBeat *odt)
{
    logdebugc("host rcv heart:[%d],%s", clptcGetAddrV1(ptcptr), odt->hdata);
    if (ptcptr->hostSndInf[0] != clptcGetAddrV1(ptcptr))
    {
        return -1;
    }
    return 1;
}
#endif
// =============command heartBeat end======================

#define CLPTC_SUB_FILE_1_MAX_SIZE (52 * 1024)
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
#define CLPTC_SUB_FILE_1_PATHNAME CLPTC_CHK_FILE_SAVE_DIR "SubRcvFile_1.txt"
#endif
// =============command wrtFileBeg begin=====================
void clptcCmdFuncOvtSnd_wrtFileBeg(clptcCmdStcSnd_wrtFileBeg *idt)
{
    idt->fileLen = ovtBigSys32(idt->fileLen);
    idt->fileId = ovtBigSys16(idt->fileId);
}
void clptcCmdFuncOvtResp_wrtFileBeg(clptcCmdStcResp_wrtFileBeg *odt)
{
    odt->packSize = ovtBigSys16(odt->packSize);
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_wrtFileBeg(clptcParseStc *ptcptr, clptcCmdUnion_wrtFileBeg *iodt)
{
    int32_t tmpflag = 0;
    // in
    logdebugc("swf beg:0x%x, 0x%x", iodt->idt.fileId, iodt->idt.fileLen);
    switch (iodt->idt.fileId)
    {
    case 1:
    {
        if (iodt->idt.fileLen >= CLPTC_SUB_FILE_1_MAX_SIZE)
        {
            tmpflag = -1;
            break;
        }
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
        // touch file. clean file.
        foptCreate(CLPTC_SUB_FILE_1_PATHNAME);
#endif
        break;
    }
    default:
    {
        break;
    }
    }
    if (tmpflag >= 0) // ok
    {
        // in
        // out
        iodt->odt.packSize = CLPTC_TSFR_FILE_LEN_MAX;
        iodt->odt.optResult = 0; // ok
    }
    else
    {
        // in
        // out
        iodt->odt.optResult = 1; // fail
    }
    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    // ptcptr->subRespCrypteHostAddr = clptcCrypte_None;
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_wrtFileBeg(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_wrtFileBeg *packDt)
{
    clptcCmdStcSnd_wrtFileBeg *tmpdata = (clptcCmdStcSnd_wrtFileBeg *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_wrtFileBeg));
    // over turn user data.
    clptcCmdFuncOvtSnd_wrtFileBeg(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_wrtFileBeg, sizeof(clptcCmdStcSnd_wrtFileBeg));
}
int clptcCmdFuncHostDoResp_wrtFileBeg(clptcParseStc *ptcptr, clptcCmdStcResp_wrtFileBeg *odt)
{
    logdebugc("host rcv write file begin: %d", odt->optResult);
    if (odt->optResult == 0)
    {
        return 1; // ok
    }
    else if (odt->optResult == 2)
    {
        return 0; // send agin!
    }
    else if (odt->optResult == 3)
    {
        return -271; // please wait.
    }
    return -1; // error
}
#endif
// =============command wrtFileBeg end======================

// =============command wrtFileSnd begin=====================
void clptcCmdFuncOvtSnd_wrtFileSnd(clptcCmdStcSnd_wrtFileSnd *idt)
{
    idt->fileOffset = ovtBigSys32(idt->fileOffset);
    idt->fileId = ovtBigSys16(idt->fileId);
    idt->packLen = ovtBigSys16(idt->packLen);
}
void clptcCmdFuncOvtResp_wrtFileSnd(clptcCmdStcResp_wrtFileSnd *odt)
{
    odt = NULL;
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_wrtFileSnd(clptcParseStc *ptcptr, clptcCmdUnion_wrtFileSnd *iodt)
{
    int tmpflag = 0;
    // in
    logdebugc("swf snd:%d,%d,%d", iodt->idt.fileOffset, iodt->idt.fileId, iodt->idt.packLen);
    switch (iodt->idt.fileId)
    {
    case 1:
    {
        if (iodt->idt.fileOffset + iodt->idt.packLen >= CLPTC_SUB_FILE_1_MAX_SIZE)
        {
            tmpflag = -1;
            break;
        }
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
        // touch file. clean file.
        fOffsetWrite(CLPTC_SUB_FILE_1_PATHNAME, iodt->idt.fileOffset, iodt->idt.packData, iodt->idt.packLen);
#endif
        break;
    }

    default:
        break;
    }
    if (tmpflag >= 0) // ok
    {
        // in
        // out
        iodt->odt.optResult = 0; // ok
    }
    else
    {
        // in
        // out
        iodt->odt.optResult = 1; // fail
    }
    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    // ptcptr->subRespCrypteHostAddr = clptcCrypte_None;
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_wrtFileSnd(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_wrtFileSnd *packDt)
{
    clptcCmdStcSnd_wrtFileSnd *tmpdata = (clptcCmdStcSnd_wrtFileSnd *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_wrtFileSnd));
    // over turn user data.
    clptcCmdFuncOvtSnd_wrtFileSnd(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_wrtFileSnd, sizeof(clptcCmdStcSnd_wrtFileSnd));
}
int clptcCmdFuncHostDoResp_wrtFileSnd(clptcParseStc *ptcptr, clptcCmdStcResp_wrtFileSnd *odt)
{
    if (odt->optResult)
    {
        logdebugc("host rcv write file transfer: %d", odt->optResult);
        return -1;
    }
    return 1;
}
#endif
// =============command wrtFileSnd end======================

// =============command wrtFileFin begin=====================
void clptcCmdFuncOvtSnd_wrtFileFin(clptcCmdStcSnd_wrtFileFin *idt)
{
    idt->fileLen = ovtBigSys32(idt->fileLen);
    idt->fileCrc = ovtBigSys32(idt->fileCrc);
    idt->fileId = ovtBigSys16(idt->fileId);
}
void clptcCmdFuncOvtResp_wrtFileFin(clptcCmdStcResp_wrtFileFin *odt)
{
    odt = NULL;
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_wrtFileFin(clptcParseStc *ptcptr, clptcCmdUnion_wrtFileFin *iodt)
{
    int32_t tmpflag = 0;
    // in
    logdebugc("swf fin:%d,%d,%d", iodt->idt.fileCrc, iodt->idt.fileId, iodt->idt.fileLen);
    switch (iodt->idt.fileId)
    {
    case 1:
    {
        if (iodt->idt.fileLen >= CLPTC_SUB_FILE_1_MAX_SIZE)
        {
            tmpflag = -1;
            break;
        }
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
        char *tmpbuf = (char *)malloc(iodt->idt.fileLen);
        if (!tmpbuf)
        {
            logdebugc("malloc error");
            tmpflag = -1;
            break;
        }
        do
        {
            tmpflag = foptRead(CLPTC_SUB_FILE_1_PATHNAME, tmpbuf, iodt->idt.fileLen);
            if (tmpflag != iodt->idt.fileLen)
            {
                logdebugc("file len error");
                tmpflag = -1;
                break;
            }
            tmpflag = calcSumCrc32((const uint8_t *)tmpbuf, iodt->idt.fileLen);
            if ((uint32_t)tmpflag != iodt->idt.fileCrc)
            {
                logdebugc("file crc error");
                tmpflag = -1;
                break;
            }
            tmpflag = 0;
        } while (0);
        // touch file. clean file.
        free(tmpbuf);
#endif
        break;
    }

    default:
        break;
    }
    if (tmpflag >= 0) // ok
    {
        // in
        // out
        iodt->odt.optResult = 0; // ok
    }
    else
    {
        // in
        // out
        iodt->odt.optResult = 1; // fail
    }
    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    // ptcptr->subRespCrypteHostAddr = clptcCrypte_None;
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_wrtFileFin(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_wrtFileFin *packDt)
{
    clptcCmdStcSnd_wrtFileFin *tmpdata = (clptcCmdStcSnd_wrtFileFin *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_wrtFileFin));
    // over turn user data.
    clptcCmdFuncOvtSnd_wrtFileFin(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_wrtFileFin, sizeof(clptcCmdStcSnd_wrtFileFin));
}
int clptcCmdFuncHostDoResp_wrtFileFin(clptcParseStc *ptcptr, clptcCmdStcResp_wrtFileFin *odt)
{
    logdebugc("host rcv write file finish: %d", odt->optResult);
    if (odt->optResult)
    {
        return -1;
    }
    return 1;
}
#endif
// =============command wrtFileFin end======================

// =============command readFileBeg begin=====================
void clptcCmdFuncOvtSnd_readFileBeg(clptcCmdStcSnd_readFileBeg *idt)
{
    idt->fileId = ovtBigSys16(idt->fileId);
}
void clptcCmdFuncOvtResp_readFileBeg(clptcCmdStcResp_readFileBeg *odt)
{
    odt->fileLen = ovtBigSys32(odt->fileLen);
    odt->fileCrc = ovtBigSys32(odt->fileCrc);
    odt->fileId = ovtBigSys16(odt->fileId);
    odt->packSize = ovtBigSys16(odt->packSize);
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_readFileBeg(clptcParseStc *ptcptr, clptcCmdUnion_readFileBeg *iodt)
{
    int32_t tmpflag = 0;
    // in
    logdebugc("srf begin:%d", iodt->idt.fileId);
    switch (iodt->idt.fileId)
    {
    case 1:
    {
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
        int tmpFileLen = fGetFileLen(CLPTC_SUB_FILE_1_PATHNAME);
        if (tmpFileLen >= 200 * 1024)
        {
            logdebugc("file is big:%d", tmpFileLen);
            tmpflag = -1;
            break;
        }
        char *tmpbuf = (char *)malloc(tmpFileLen);
        if (!tmpbuf)
        {
            logdebugc("malloc error");
            tmpflag = -1;
            break;
        }
        do
        {
            int tmpReadLen = foptRead(CLPTC_SUB_FILE_1_PATHNAME, tmpbuf, tmpFileLen);
            if (tmpReadLen != tmpFileLen)
            {
                logdebugc("file len error");
                tmpflag = -1;
                break;
            }
            iodt->odt.fileId = iodt->idt.fileId;
            iodt->odt.packSize = CLPTC_TSFR_FILE_LEN_MAX;
            iodt->odt.fileLen = tmpFileLen;
            iodt->odt.fileCrc = calcSumCrc32((const uint8_t *)tmpbuf, tmpFileLen);
        } while (0);
        // touch file. clean file.
        free(tmpbuf);
#endif
        break;
    }
    default:
    {
        break;
    }
    }
    if (tmpflag >= 0) // ok
    {
        // in
        // out
        iodt->odt.optResult = 0; // ok
    }
    else
    {
        // in
        // out
        iodt->odt.optResult = 1; // fail
    }
    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    // ptcptr->subRespCrypteHostAddr = clptcCrypte_None;
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_readFileBeg(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_readFileBeg *packDt)
{
    clptcCmdStcSnd_readFileBeg *tmpdata = (clptcCmdStcSnd_readFileBeg *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_readFileBeg));
    // over turn user data.
    clptcCmdFuncOvtSnd_readFileBeg(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_readFileBeg, sizeof(clptcCmdStcSnd_readFileBeg));
}
int clptcCmdFuncHostDoResp_readFileBeg(clptcParseStc *ptcptr, clptcCmdStcResp_readFileBeg *odt)
{
    logdebugc("host rcv read file begin: %d", odt->optResult);
    if (odt->optResult)
    {
        return -1;
    }
    return 1;
}
#endif
// =============command readFileBeg end======================

// =============command readFileRcv begin=====================
void clptcCmdFuncOvtSnd_readFileRcv(clptcCmdStcSnd_readFileRcv *idt)
{
    idt->fileOffset = ovtBigSys32(idt->fileOffset);
    idt->fileId = ovtBigSys16(idt->fileId);
    idt->packLen = ovtBigSys16(idt->packLen);
}
void clptcCmdFuncOvtResp_readFileRcv(clptcCmdStcResp_readFileRcv *odt)
{
    odt = NULL;
}
#if CLPTC_CPL_SUB_ENABLE
void clptcCmdFuncSubDo_readFileRcv(clptcParseStc *ptcptr, clptcCmdUnion_readFileRcv *iodt)
{
    int tmpflag = 0;
    // in
    logdebugc("srf transfer:%d,%d,%d", iodt->idt.fileOffset, iodt->idt.fileId, iodt->idt.packLen);
    switch (iodt->idt.fileId)
    {
    case 1:
    {
        if (iodt->idt.packLen > CLPTC_TSFR_FILE_LEN_MAX)
        {
            logdebugc("packLen error");
            tmpflag = -1;
            break;
        }
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
        char *tmpbuf = (char *)malloc(iodt->idt.packLen);
        if (!tmpbuf)
        {
            logdebugc("malloc error");
            tmpflag = -1;
            break;
        }
        do
        {
            int tmpReadLen = fOffsetRead(CLPTC_SUB_FILE_1_PATHNAME, iodt->idt.fileOffset, tmpbuf, iodt->idt.packLen);
            if (tmpReadLen != iodt->idt.packLen)
            {
                logdebugc("read file error:%d,%d", tmpReadLen, iodt->idt.packLen);
                tmpflag = -1;
                break;
            }
            memcpy(iodt->odt.packData, tmpbuf, tmpReadLen);
        } while (0);
        // touch file. clean file.
        free(tmpbuf);
#endif
        break;
    }
    default:
    {
        break;
    }
    }
    if (tmpflag >= 0) // ok
    {
        // in
        // out
        iodt->odt.optResult = 0; // ok
    }
    else
    {
        // in
        // out
        iodt->odt.optResult = 1; // fail
    }
    // set response encrypte type(0), response size(0), response flag(0). not set, use default.
    // ptcptr->subRespCrypteHostAddr = clptcCrypte_None;
    ptcptr->subRespSizeHostCmdId = sizeof(iodt->odt);
}
#endif
#if CLPTC_CPL_HOST_ENABLE
int clptcCmdFuncHostPack_readFileRcv(clptcParseStc *ptcptr, int packAddr, int packCrypt, clptcCmdStcSnd_readFileRcv *packDt)
{
    clptcCmdStcSnd_readFileRcv *tmpdata = (clptcCmdStcSnd_readFileRcv *)clptcGetDataPtrV1(ptcptr);
    memcpy(tmpdata, packDt, sizeof(clptcCmdStcSnd_readFileRcv));
    // over turn user data.
    clptcCmdFuncOvtSnd_readFileRcv(tmpdata);
    return clptcHostPackCommV1(ptcptr, packAddr, packCrypt, clptcCmdEnum_readFileRcv, sizeof(clptcCmdStcSnd_readFileRcv));
}
int clptcCmdFuncHostDoResp_readFileRcv(clptcParseStc *ptcptr, clptcCmdStcResp_readFileRcv *odt)
{
    if (odt->optResult)
    {
        logdebugc("host rcv read file transfer: %d", odt->optResult);
        return -1;
    }
    return 1;
}
#endif
// =============command readFileRcv end======================

#if CLPTC_CPL_SUB_ENABLE
#define SWITH_SUB_CMD_ID_FUNC(cmdname)                                                             \
    case clptcCmdEnum_##cmdname:                                                                   \
    {                                                                                              \
        clptcCmdFuncOvtSnd_##cmdname((clptcCmdStcSnd_##cmdname *)clptcGetDataPtrV1(ptcptr));       \
        clptcCmdFuncSubDo_##cmdname(ptcptr, (clptcCmdUnion_##cmdname *)clptcGetDataPtrV1(ptcptr)); \
        clptcCmdFuncOvtResp_##cmdname((clptcCmdStcResp_##cmdname *)clptcGetDataPtrV1(ptcptr));     \
        break;                                                                                     \
    }
int clptcCmdSubDealByID(clptcParseStc *ptcptr)
{
    switch (clptcGetCmdIdV1(ptcptr))
    {
        SWITH_SUB_CMD_ID_FUNC(rwSn);
        SWITH_SUB_CMD_ID_FUNC(rwAddr);
        SWITH_SUB_CMD_ID_FUNC(getInf);
        SWITH_SUB_CMD_ID_FUNC(setsm4key);
        SWITH_SUB_CMD_ID_FUNC(heartBeat);
        SWITH_SUB_CMD_ID_FUNC(wrtFileBeg);
        SWITH_SUB_CMD_ID_FUNC(wrtFileSnd);
        SWITH_SUB_CMD_ID_FUNC(wrtFileFin);
        SWITH_SUB_CMD_ID_FUNC(readFileBeg);
        SWITH_SUB_CMD_ID_FUNC(readFileRcv);
    default:
    {
        logerrorc("%d", clptcGetCmdIdV1(ptcptr));
        return -1;
    }
    }
    return 0;
}
#endif

#if CLPTC_CPL_HOST_ENABLE
#define SWITH_HOST_CMD_ID_FUNC(cmdname)                                                                          \
    case clptcCmdEnumDef(cmdname):                                                                               \
    {                                                                                                            \
        clptcCmdFuncOvtResp_##cmdname((clptcCmdStcResp_##cmdname *)clptcGetDataPtrV1(ptcptr));                   \
        return clptcCmdFuncHostDoResp_##cmdname(ptcptr, (clptcCmdStcResp_##cmdname *)clptcGetDataPtrV1(ptcptr)); \
    }
int clptcCmdHostDealByID(clptcParseStc *ptcptr)
{
    switch (clptcGetCmdIdV1(ptcptr))
    {
        SWITH_HOST_CMD_ID_FUNC(rwSn);
        SWITH_HOST_CMD_ID_FUNC(rwAddr);
        SWITH_HOST_CMD_ID_FUNC(getInf);
        SWITH_HOST_CMD_ID_FUNC(setsm4key);
        SWITH_HOST_CMD_ID_FUNC(heartBeat);
        SWITH_HOST_CMD_ID_FUNC(wrtFileBeg);
        SWITH_HOST_CMD_ID_FUNC(wrtFileSnd);
        SWITH_HOST_CMD_ID_FUNC(wrtFileFin);
        SWITH_HOST_CMD_ID_FUNC(readFileBeg);
        SWITH_HOST_CMD_ID_FUNC(readFileRcv);
    default:
    {
        logerrorc("%d", clptcGetCmdIdV1(ptcptr));
        break;
    }
    }
    return 0;
}
#endif
